/*
 * Authors: Alex Attar & Kevin El Hage
 * ID: 9765727
 * Date: 9/3/2012
 * 
 */

package taskManagerSystem.ViewSubsystem;

import javax.swing.*;
import javax.swing.event.*;

import taskManagerSystem.ModelSubsystem.Model;
import taskManagerSystem.ModelSubsystem.Person;
import taskManagerSystem.ModelSubsystem.Task;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.*;
import java.util.Vector;

/*
 * The View class manages the view of the system and the display of data.
 */
public class View {
	String[] taskCols = {"ID", "Title", "Description", "Duration", "Deliverable", "Deadline", "Person"};
	Class<?>[] taskTypes = {Integer.class, String.class, String.class, Integer.class, String.class, String.class, String.class};
	
	String[] personCols = {"ID", "Name", "Total Hours", "Tasks"};
	Class<?>[] personTypes = {Integer.class, String.class, Integer.class, String.class};
	
	// Simply a series of Swing components used to display the information
	private JFrame window;
	private JPanel dataPanel;
	private JPanel taskPanel;
	private JPanel personPanel;
	
	private JLabel taskLabel;
	private JLabel personLabel;
	
	private JScrollPane taskScroller;
	private JScrollPane personScroller;
	
	private TaskView taskView;
	private PersonView personView;
	
	private JMenuBar menuBar;
	private JMenu fileMenu;
	private JMenuItem newMenuItem;
	private JMenuItem loadMenuItem;
	private JMenuItem saveMenuItem;
	private JMenuItem exitMenuItem;
	private JMenu editMenu;
	private JMenuItem newTaskMenuItem;
	private JMenuItem delTaskMenuItem;
	
	private Model model;
	
	/*
	 * The constructor receives a references to the model and ensures that it is empty on creation.
	 */
	public View(Model model){
		initUI();
		this.model = model;
		this.model.clearData();
	}
	
	/*
	 * initUI() initializes all of the Swing components and positions them correctly.
	 * This should only be called once when the View is created.
	 */
	private void initUI(){

		// Create all of the components
		window = new JFrame();
		dataPanel = new JPanel();
		taskPanel = new JPanel();
		personPanel = new JPanel();
		taskLabel = new JLabel("Task View", JLabel.CENTER);
		personLabel = new JLabel("Person View", JLabel.CENTER);
		menuBar = new JMenuBar();
		fileMenu = new JMenu("File");
		newMenuItem = new JMenuItem("New");
		loadMenuItem = new JMenuItem("Load");
		saveMenuItem = new JMenuItem("Save");
		exitMenuItem = new JMenuItem("Exit");
		editMenu = new JMenu("Edit");
		newTaskMenuItem = new JMenuItem("New task");
		delTaskMenuItem = new JMenuItem("Delete task");
		
		// Set up the window
		window.setTitle("Task Manager");
		window.setSize(800, 600);
		window.setLocationRelativeTo(null);
		window.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		
		// Set up the File menu and its items
		fileMenu.setMnemonic(KeyEvent.VK_F);
		newMenuItem.setMnemonic(KeyEvent.VK_N);
		loadMenuItem.setMnemonic(KeyEvent.VK_L);
		saveMenuItem.setMnemonic(KeyEvent.VK_S);
		exitMenuItem.setMnemonic(KeyEvent.VK_X);
		
		// Add items to File menu
		fileMenu.add(newMenuItem);
		fileMenu.add(loadMenuItem);
		fileMenu.add(saveMenuItem);
		fileMenu.add(exitMenuItem);
		
		// Add File menu to menu bar
		menuBar.add(fileMenu);
		
		// Set up the Edit menu and its items
		editMenu.setMnemonic(KeyEvent.VK_E);
		newTaskMenuItem.setMnemonic(KeyEvent.VK_T);
		delTaskMenuItem.setMnemonic(KeyEvent.VK_D);
		
		// Add items to Edit menu
		editMenu.add(newTaskMenuItem);
		editMenu.add(delTaskMenuItem);
		
		// Add Edit menu to menu bar
		menuBar.add(editMenu);
		
		// Set the window's menu bar to the newly instanced menuBar
		window.setJMenuBar(menuBar);
		
		//create a panel dataPanel that will include both 
		//taskPanel and personPanel and display the tables in 
		//grid format
		dataPanel.setLayout(new GridLayout(2,1));
		
		// Set up the two tables
		//task table
		taskView = new TaskView(taskCols, taskTypes);
		
		//set layout of task table panel to border layout
		taskPanel.setLayout(new BorderLayout());
		
		taskScroller = new JScrollPane(taskView);
		
		Component[] c = taskScroller.getComponents();
		for(int i=0; i!=c.length; i++){
			c[i].setBackground(new Color(255, 255, 255));
		}
		
		//add a label (title) for the task table
		taskPanel.add(taskLabel , BorderLayout.NORTH);
		
		//add a scroller to task panel
		taskPanel.add(taskScroller);
		
		//person table
		personView = new PersonView(personCols, personTypes);
		
		//set layout of person table panel to border layout
		personPanel.setLayout(new BorderLayout());
		
		personScroller = new JScrollPane(personView);
		
		c = personScroller.getComponents();
		for(int i=0; i!=c.length; i++){
			c[i].setBackground(new Color(255, 255, 255));
		}
		
		//add a label (title) for the person table
		personPanel.add(personLabel, BorderLayout.NORTH);
		
		//add a scroller to person panel
		personPanel.add(personScroller);
		
		//add both panels to data panel
		dataPanel.add(taskPanel);
		dataPanel.add(personPanel);
		
		//add the data panel to the window
		window.add(dataPanel);
	}
	
	/*
	 * setVisible makes the window visible. 
	 */
	public void setVisible(boolean visible){
		window.setVisible(visible);
	}
	
	/*
	 * Returns whether or not the window is visible.
	 */
	public boolean isVisible(){
		return window.isVisible();
	}
	
	/*
	 * emptyTaskTable and emptyPersonTable clear and redraw the two tables and reset their scroll bars.
	 */
	public void emptyTaskTable(){
		taskView.empty();
		taskView.repaint();
		taskScroller.revalidate();
	}
	
	public void emptyPersonTable(){
		personView.empty();
		personView.repaint();
		personScroller.revalidate();
	}
	
	/*
	 * getSelectedTaskID returns the ID of the task in the selected row.
	 */
	public int getSelectedTaskID(){
		int row = taskView.getSelectedRow();
		int taskID = Integer.parseInt((String) taskView.getValueAt(row, 0));
		return taskID;
	}
	
	/*
	 * getSelectedRow returns the number of the row selected, or -1 if none is selected.
	 */
	public int getSelectedRow(){
		return taskView.getSelectedRow();
	}
	
	/*
	 * populateTaskTable retrieves a Vector of tasks from the model and creates
	 * a row in the table for each task.
	 */
	public void populateTaskTable(){
		Vector<Task> data = model.getTasks();
		taskView.empty();
		for(int i=0; i!=data.size(); i++){
			String[] row = new String[7];
			Task task = data.get(i);
			row[0] = String.valueOf(task.getTaskID());
			row[1] = task.getTitle();
			row[2] = task.getDescription();
			row[3] = String.valueOf(task.getDuration());
			row[4] = task.getDeliverable();
			row[5] = task.getDeadlineDate();
			row[6] = task.getPerson();
			taskView.addRow(row);
		}
		taskView.repaint();
		
	}
	
	/*
	 * populatePersonTable retrieves a Vector of people from the model and
	 * creates a row in the table for each person.
	 */
	public void populatePersonTable(){
		Vector<Person> data = model.getPeople();
		personView.empty();
		for(int i=0; i!=data.size(); i++){
			String[] row = new String[4];
			Person person = data.get(i);
			row[0] = String.valueOf(i+1);
			row[1] = person.getName();
			row[2] = String.valueOf(person.getTotalHours());
			row[3] = person.getListOfTasks();
			personView.addRow(row);
		}
		personView.repaint();
	}
	
	/*
	 * addActionListeners adds the listener to each menu item. 
	 */
	public void addActionListeners(ActionListener l){
		newMenuItem.addActionListener(l);
		loadMenuItem.addActionListener(l);
		saveMenuItem.addActionListener(l);
		newTaskMenuItem.addActionListener(l);
		delTaskMenuItem.addActionListener(l);
		exitMenuItem.addActionListener(l);
	}
	
	/*
	 * addTaskTableListener adds the listener to the task table.
	 * NOTE: There is no addPersonTableListener method as the person table
	 * should never be directly modified. 
	 */
	public void addTaskTableListener(TableModelListener l){
		taskView.addTableListener(l);
	}
	
	/*
	 * addWindowSaveOnExitListener adds a listener to the window.
	 */
	public void addWindowSaveOnExitListener(WindowListener e) {
		window.addWindowListener(e);
	}
	
}
